const _ = require("lodash");
const {
  readAllValues,
} = require("../awakened-potential/helpers/readAllValues.js");

/**
 * 预测函数：从部分历史数据中预测下一期可能出现的号码
 * @param {Array<{ time: string, number: number }>} history 用于预测的历史数据
 * @param {Object} options 配置项
 * @returns {{ hot: number[], cold: number[], recommend: number[] }}
 */
function predictNextNumber(history, options = {}) {
  const hotCount = options.hotCount || 12;
  const coldCount = options.coldCount || 12;

  const countMap = Array(50).fill(0); // 0 号不用

  for (const item of history) {
    const number = Number(item.number); // 强制转换为数字
    if (number >= 1 && number <= 49) {
      countMap[number]++;
    }
  }

  const result = countMap.map((count, number) => ({ number, count })).slice(1);

  const hotNumbers = _.orderBy(result, ["count", "number"], ["desc", "asc"])
    .slice(0, hotCount)
    .map((item) => item.number);

  const coldNumbers = _.orderBy(result, ["count", "number"], ["asc", "asc"])
    .slice(0, coldCount)
    .map((item) => item.number);

  const recommend = _.uniq([...hotNumbers, ...coldNumbers]);

  return {
    hot: hotNumbers,
    cold: coldNumbers,
    recommend: recommend.sort((a, b) => a - b),
  };
}

/**
 * 分析连续段落（成功/失败）
 * @param {number[]} arr 命中数组（1表示成功，0表示失败）
 * @returns 分析结果对象
 */
function analyzeStreaks(arr) {
  let streaks1 = [];
  let streaks0 = [];

  let current = arr[0];
  let count = 1;

  for (let i = 1; i < arr.length; i++) {
    if (arr[i] === current) {
      count++;
    } else {
      if (current === 1) streaks1.push(count);
      else streaks0.push(count);
      current = arr[i];
      count = 1;
    }
  }

  // 最后一段
  if (current === 1) streaks1.push(count);
  else streaks0.push(count);

  const maxStreak1 = Math.max(...streaks1, 0);
  const maxStreak0 = Math.max(...streaks0, 0);

  const avgStreak1 =
    streaks1.length > 0
      ? (streaks1.reduce((a, b) => a + b, 0) / streaks1.length).toFixed(2)
      : "0.00";
  const avgStreak0 =
    streaks0.length > 0
      ? (streaks0.reduce((a, b) => a + b, 0) / streaks0.length).toFixed(2)
      : "0.00";

  return {
    maxStreak1,
    maxStreak0,
    avgStreak1,
    avgStreak0,
    streaks1,
    streaks0,
  };
}

// ========== ✅ 主执行逻辑 ==========
const historyDataRaw = readAllValues("m");

// 强制 number 字段为数字类型
const historyData = historyDataRaw.map((item) => ({
  time: item.time,
  number: Number(item.number),
}));

const windowSize = 100;        // 滑动窗口大小，用于历史数据分析
const hotCount = 21;           // 热号数量，选择出现频率最高的前21个号码
const coldCount = 11;          // 冷号数量，选择出现频率最低的前11个号码

let correct = 0;               // 预测正确的次数统计
let wrong = 0;                 // 预测错误的次数统计
let hitArray = [];             // 存储每次预测的命中情况（1表示命中，0表示未命中）

console.log(
  `\n🧠 使用滑动窗口预测（窗口大小：${windowSize}），共 ${
    historyData.length - windowSize
  } 次预测：\n`
);

for (let i = windowSize; i < historyData.length; i++) {
  const windowData = historyData.slice(i - windowSize, i);
  const actual = historyData[i];

  const prediction = predictNextNumber(windowData, { hotCount, coldCount });
  const hit = prediction.recommend.includes(actual.number);

  hitArray.push(hit ? 1 : 0);
  if (hit) correct++;
  else wrong++;

  if(prediction.recommend.length !== 32) {
    console.log(`📅 第${i + 1}期（${actual.time}）`);
    console.log(`🔥 热号(${prediction.hot.length}):`, prediction.hot.join(", "));
    console.log(
      `❄️ 冷号(${prediction.cold.length}):`,
      prediction.cold.join(", ")
    );
    console.log(
      `🎯 推荐(${prediction.recommend.length}):`,
      prediction.recommend.join(", ")
    );
    console.log(
      `✅ 实际号码: ${actual.number} → 是否命中: ${hit ? "✅ 是" : "❌ 否"}`
    );
    console.log("---------------------------------------------------\n");
  }

}

// 命中率统计
const total = correct + wrong;
const accuracy = total > 0 ? ((correct / total) * 100).toFixed(2) : "0.00";

// 连续段落分析
const { maxStreak1, maxStreak0, avgStreak1, avgStreak0, streaks1, streaks0 } =
  analyzeStreaks(hitArray);

console.log("\n🎯 预测结果统计");
console.log(`总预测期数: ${total}`);
console.log(`✅ 命中期数: ${correct}`);
console.log(`❌ 错误期数: ${wrong}`);
console.log(`📊 命中率: ${accuracy}%`);

console.log("\n📈 连续预测表现分析：");
console.log(`✅ 最大连续命中次数: ${maxStreak1} 次`);
console.log(`❌ 最大连续失败次数: ${maxStreak0} 次`);
console.log(`✅ 成功段落数量: ${streaks1.length}`);
console.log(`❌ 错误段落数量: ${streaks0.length}`);
console.log(`✅ 成功段落平均长度: ${avgStreak1} 次`);
console.log(`❌ 错误段落平均长度: ${avgStreak0} 次`);


/*
🎯 预测结果统计
总预测期数: 1145
✅ 命中期数: 751
❌ 错误期数: 394
📊 命中率: 65.59%

📈 连续预测表现分析：
✅ 最大连续命中次数: 13 次
❌ 最大连续失败次数: 5 次
✅ 成功段落数量: 252
❌ 错误段落数量: 251
✅ 成功段落平均长度: 2.98 次
❌ 错误段落平均长度: 1.57 次
//*/